import traceback
from time import sleep
from crawlers.utils import fetch_json_data, parse_timestamp
from crawlers.constants import (
    REQUEST_HEADERS,
    SSPAI_BASE_URL,
    SSPAI_HOT_ARTICLES_API,
    SSPAI_RECOMMENDED_ARTICLES_API,
)


def _process_photo_url(url, url_type):
    """处理图片链接，将其转换为对应的URL

    Parameters:
        url: 图片链接
        url_type: 图片类型，"banner"表示横幅图，"avatar"表示头像图

    Returns:
        处理后的图片链接
    """

    if url_type == "banner":
        if url.startswith("https"):
            return f"{url}?imageMogr2/auto-orient/thumbnail/!800x400r/gravity/center/crop/800x400/format/webp/ignore-error/1"
        return f"https://cdnfile.sspai.com/{url}?imageMogr2/auto-orient/thumbnail/!800x400r/gravity/center/crop/800x400/format/webp/ignore-error/1"
    elif url_type == "avatar":
        if url.startswith("https"):
            return f"{url}?imageMogr2/auto-orient/thumbnail/!48x48r/gravity/center/crop/48x48/format/webp/ignore-error/1"
        return f"https://cdnfile.sspai.com/{url}?imageMogr2/auto-orient/thumbnail/!48x48r/gravity/center/crop/48x48/format/webp/ignore-error/1"
    else:
        return url


def _extract_sspai_article_info(json_data, order):
    """从json_data中提取文章信息，并返回一个包含文章信息的字典

    Parameters:
        json_data: JSON数据
        order: 文章序号

    Returns:
        文章信息字典，包含序号、标题、链接、简介、图片链接、创建时间、点赞数、评论数和作者信息

    """
    article_info = {}
    article_info["order"] = order
    article_info["title"] = json_data["title"]
    article_info["url"] = f"{SSPAI_BASE_URL}/post/{json_data['id']}"
    article_info["intro"] = json_data["summary"]
    article_info["photo_url"] = _process_photo_url(json_data["banner"], "banner")
    article_info["created_at"] = parse_timestamp(json_data["created_time"])
    article_info["likes"] = json_data["like_count"]
    article_info["comment_count"] = json_data["comment_count"]
    author = json_data["author"]
    article_info["authors"] = [
        {
            "name": author["nickname"],
            "photo_url": _process_photo_url(author["avatar"], "avatar"),
            "url": f"{SSPAI_BASE_URL}/u/{author['slug']}",
        }
    ]
    corner = json_data.get("corner")
    if corner and corner.get("name"):
        article_info["corner"] = {
            "name": corner["name"],
            "icon_url": corner.get("icon"),
        }

    return article_info


def _get_articles_from_sspai(section):
    """获取不同板块的少数派文章信息

    Parameters:
        section: 板块名称，"hot"表示热门文章，"recommended"表示推荐文章

    Returns:
        文章信息列表，每个文章包含序号、标题、链接、简介、图片链接、创建时间、点赞数、评论数和作者信息
    """
    try:
        section_info = {
            "latest": {
                "url": SSPAI_HOT_ARTICLES_API,
                "params": {
                    "limit": 10,
                    "offset": 0,
                    "created_at": 0,
                    "tag": "热门文章",
                    "released": False,
                },
                "error": "获取少数派最新文章失败",
            },
            "recommended": {
                "url": SSPAI_RECOMMENDED_ARTICLES_API,
                "params": {"limit": 10, "offset": 0, "created_at": 0},
                "error": "获取少数派推荐文章失败",
            },
        }

        config = section_info.get(section)
        if not config:
            raise ValueError(f"不支持的板块类型: {section}")
        articles = []
        order = 1
        for offset in [0, 10, 20]:
            config["params"]["offset"] = offset
            json_data = fetch_json_data(
                config["url"],
                headers=REQUEST_HEADERS,
                params=config["params"],
                encoding="utf-8",
            )
            for item in json_data:
                article_info = _extract_sspai_article_info(item, order)
                order += 1

                articles.append(article_info)
            sleep(1)
        return articles
    except Exception as e:
        print(f"{config['error']}: {e}")
        print("详细错误信息:")
        traceback.print_exc()
        raise


def get_latest_articles_from_sspai():
    """从少数派获取热门文章数据

    Returns:
        热门文章数据列表，每个文章包含序号、标题、链接和热度、标签和图片链接信息
    """
    return _get_articles_from_sspai("latest")


def get_recommended_articles_from_sspai():
    """从少数派获取推荐文章数据

    Returns:
        推荐文章数据列表，每个文章包含序号、标题、链接和热度、标签和图片链接信息
    """
    return _get_articles_from_sspai("recommended")
